#include "user_adc.h"

/* ADC采样值数组 */
__IO uint32_t adc_ordinary_valuetab[3];

/**
  * @brief  ADC初始化函数
  * @param  None
  * @retval None
  */
void adc_init(void)
{
  gpio_init_type gpio_init_struct;
  adc_base_config_type adc_base_struct;
  dma_init_type dma_init_struct;

  /* 使能ADC、GPIO和DMA时钟 */
  crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);

  /* 配置GPIO为模拟输入模式 */
  gpio_init_struct.gpio_pins = ADC_CHANNEL_0_PIN | ADC_CHANNEL_1_PIN | ADC_CHANNEL_2_PIN;
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(ADC_CHANNEL_0_PORT, &gpio_init_struct);

  /* 配置DMA */
//  dma_reset(DMA1_CHANNEL1);
//  dma_default_para_init(&dma_init_struct);
//  dma_init_struct.buffer_size = 3;
//  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
//  dma_init_struct.memory_base_addr = (uint32_t)adc_ordinary_valuetab;
//  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;
//  dma_init_struct.memory_inc_enable = TRUE;
//  dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt);
//  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
//  dma_init_struct.peripheral_inc_enable = FALSE;
//  dma_init_struct.priority = DMA_PRIORITY_HIGH;
//  dma_init_struct.loop_mode_enable = FALSE;
//  dma_init(DMA1_CHANNEL1, &dma_init_struct);

//  dma_channel_enable(DMA1_CHANNEL1, TRUE);
  crm_adc_clock_div_set(CRM_ADC_DIV_6);
  /* 复位ADC */
  adc_reset(ADC1);

  /* 配置ADC基本参数 */
  adc_combine_mode_select(ADC_ORDINARY_SMLT_ONLY_MODE);
  adc_base_default_para_init(&adc_base_struct);
  adc_base_struct.sequence_mode = TRUE;
  adc_base_struct.repeat_mode = FALSE;
  adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
  adc_base_struct.ordinary_channel_length = 3;
  adc_base_config(ADC1, &adc_base_struct);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_1, 1, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2, 2, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_3, 3, ADC_SAMPLETIME_239_5);
  adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

  /* 配置ADC通道和采样时间 */
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0_ADC_CHANNEL, 1, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_1_ADC_CHANNEL, 2, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2_ADC_CHANNEL, 3, ADC_SAMPLETIME_239_5);

  /* 配置ADC触发源为软件触发 */
  adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

  /* 使能ADC DMA */
  adc_dma_mode_enable(ADC1, TRUE);

  /* 使能ADC */
  adc_enable(ADC1, TRUE);

  /* ADC校准 */
  adc_calibration_init(ADC1);
  while(adc_calibration_init_status_get(ADC1));
  adc_calibration_start(ADC1);
  while(adc_calibration_status_get(ADC1));
}

/**
  * @brief  获取ADC采样值
  * @param  channel: ADC通道号(0-2)
  * @retval ADC采样值(0-4095)
  */
uint16_t adc_get_value(uint8_t channel)
{
  /* 检查通道号是否有效 */
  if(channel > 2)
  {
    return 0;
  }

  /* 启动ADC转换 */
  adc_ordinary_software_trigger_enable(ADC1, TRUE);

  /* 等待DMA传输完成 */
  while(dma_flag_get(DMA1_FDT1_FLAG) == RESET);
  dma_flag_clear(DMA1_FDT1_FLAG);

  /* 返回对应通道的值 */
  return (uint16_t)(adc_ordinary_valuetab[channel] & 0xFFFF);
} 